package com.yuyou.fn.educational.service.impl;

import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.educational.entity.CourseClass;
import com.yuyou.fn.educational.entity.Teacher;
import com.yuyou.fn.educational.mapper.CourseClassMapper;
import com.yuyou.fn.educational.service.ITeacherService;
import com.yuyou.fn.educational.vo.ArrangeClassTimeResultVo;
import org.springframework.stereotype.Service;

import com.yuyou.fn.educational.mapper.ClassTimeMapper;
import com.yuyou.fn.educational.entity.ClassTime;
import com.yuyou.fn.educational.entity.CourseClass;
import com.yuyou.fn.educational.mapper.ClassTimeMapper;
import com.yuyou.fn.educational.service.IClassTimeService;
import com.github.wens.framework.service.impl.SuperServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 *
 * ClassTime 表数据服务层接口实现类
 *
 */
@Service
public class ClassTimeServiceImpl extends SuperServiceImpl<ClassTimeMapper, ClassTime,Long> implements IClassTimeService {

    @Resource
    private ITeacherService teacherService;

    @Override
    public void createClassTime(Long classId, Integer lectureAmount) {
        List<ClassTime> list  = new ArrayList<>(lectureAmount);
        for(int i = 1 ;i <= lectureAmount ;i++ ){
            ClassTime classTime = new ClassTime() ;
            classTime.setClassId(classId);
            classTime.setLectureNo(i);
            classTime.setCreateTime(TimeUtils.now());
            classTime.setUpdateTime(TimeUtils.now());
            list.add(classTime);
        }
        insertBatch(list);
    }

    @Override
    public void saveArrangeClassTimeResult(Long classId, List<ArrangeClassTimeResultVo> arrangeClassTimeResultList) {
        for(int i = 1 ;i <= arrangeClassTimeResultList.size() ;i++ ){
            ArrangeClassTimeResultVo arrangeClassTimeResultVo = arrangeClassTimeResultList.get(i - 1);

            Example<ClassTime> example = ClassTime.createExample();
            example.createCriteria().andEqualTo("classId" , classId).andEqualTo("lectureNo" , i );
            ClassTime classTime = new ClassTime();
            classTime.setClassDate(TimeUtils.parse(arrangeClassTimeResultVo.getDate(),"yyyy-MM-dd"));
            String[] times = arrangeClassTimeResultVo.getTime().split("-");
            classTime.setStartTime(times[0]);
            classTime.setEndTime(times[1]);
            boolean s = updateSelectiveByExample(classTime, example);
            if(!s){
                saveClassTime(classId, i, classTime);
            }
        }

    }

    public ClassTime findByClassIdLectureNo(Long classId, int lectureNo) {
        Example<ClassTime> example = ClassTime.createExample();
        example.createCriteria().andEqualTo("classId" , classId).andEqualTo("lectureNo" , lectureNo );
        return findOneByExample(example);
    }

    @Override
    public Page<ClassTime> findClassTimeByClassId(Long classId, int pageNo, int pageSize) {
        Example<ClassTime> example = ClassTime.createExample();
        example.orderBy("lectureNo").asc();
        example.createCriteria().andEqualTo("classId", classId);
        return findPageByExample(example, pageNo, pageSize);
    }

    @Override
    public List<ClassTime> findClassTimeByClassId(Long classId) {
        Example<ClassTime> example = ClassTime.createExample();
        example.orderBy("lectureNo");
        example.createCriteria().andEqualTo("classId",classId);
        return findListByExample(example);
    }

    @Transactional
    @Override
    public void saveArrangementTeacher(Long classId, List<Long> teacherIds) {
        List<Teacher> teacherList = teacherService.findByIds(teacherIds);
        Map<Long , Teacher> teacherMap = BeanUtils.toMap(teacherList,"teacherId");
        List<ClassTime> classTimeList = findClassTimeByClassId(classId);
        Map<Integer,ClassTime> classTimeMap = BeanUtils.toMap(classTimeList,"lectureNo");
        for(int i = 1 ;i <= teacherIds.size() ;i++ ){
            ClassTime classTime = classTimeMap.get(i);
            ClassTime update = new ClassTime();
            update.setClassTimeId(classTime.getClassTimeId());
            Long teacherId = teacherIds.get(i - 1);
            update.setTeacherId(teacherId );
            update.setTeacherName(teacherMap.get(teacherId).getTeacherName());
            if( detectConflict(teacherId,classTime.getClassDate(),classTime.getStartTime(),classTime.getEndTime() )){
                throw new BusException("【第"+classTime.getLectureNo()+"讲】时间有冲突");
            }
            updateSelectiveById(update);
        }
    }

    private boolean detectConflict(Long teacherId ,Date classDate , String startTime , String endTime  ) {
        Example<ClassTime> example = ClassTime.createExample();
        example.createCriteria().andEqualTo("teacherId",teacherId ).andEqualTo("classDate",classDate );
        List<ClassTime> timeList = findListByExample(example);

        if(timeList.size() != 0 ){
            for(ClassTime t : timeList ){
                if( ( startTime.compareTo(t.getStartTime()) > 0 &&  startTime.compareTo(t.getEndTime()) <=0 ) ||
                        ( endTime.compareTo(t.getStartTime()) > 0 &&  endTime.compareTo(t.getEndTime()) <=0 ) ){
                    return true;
                }
            }
        }
        return false ;
    }

    private void saveClassTime(Long classId, int lectureNo, ClassTime classTime) {
        classTime.setClassId(classId);
        classTime.setLectureNo(lectureNo);
        classTime.setCreateTime(TimeUtils.now());
        classTime.setUpdateTime(TimeUtils.now());
        insertSelective(classTime);
    }

    @Override
    public List<ClassTime> findClassTimeByTeacherId(Long teacherId, Date start, Date end) {
        Example<ClassTime> example = ClassTime.createExample();
        example.createCriteria().andEqualTo("teacherId",teacherId).andBetween("classDate" ,start ,end );
        return findListByExample(example);
    }

    @Override
    public List<ClassTime> findClassTimeByClassIdAndDateString(Long classId, String  dateString) {
        Example<ClassTime> example = ClassTime.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andEqualTo("classId",classId);
        criteria.andLike("classDate",dateString+"%");
        example.orderBy("classDate");
        return findListByExample(example);
    }
}